package org.batatasframework.expression;


/**
* <pre>
* 对应的表达式的名字部分，
* 如：
* name = -f my -m 100 
* 或 
* place[广州、深圳...] = -f my -m 100
* 
* 这里是名字部分，如上："name"或"place[广州、深圳...]"
* 
* 其中的"[广州、深圳...]"部分会解析成{@link #extra}值，可对表达式进行扩展
* </pre>
* 
* <pre>
* 一个名字的定义，这个名字是通用的，包括使用"."进行分隔的多级命名
* </pre>
* 
* @author jackson
*
*/
public class Named {
	
	public static final String HIERARCHY_SEPARATOR = ".";
	public static final String HIERARCHY_SEPARATOR_REGEX = "\\" + HIERARCHY_SEPARATOR;
	
	public static final Named NULL_VALUE = new Named();
	
	public static Named valueOf(String name){
		if(null != name){
			name = adjust(name);
			if(!name.isEmpty()) return new Named(name);
		}
		
		return NULL_VALUE;
	}

	/** 主要是去掉字符串前面和后面的"." */
	public static String adjust(String name){
		if(name.startsWith(HIERARCHY_SEPARATOR)) name = name.substring(1);
		if(name.endsWith(HIERARCHY_SEPARATOR)) name = name.substring(0, name.length() - 1);
		return name;
	}
	
	public static String concat(String parent, String name){
		return adjust(parent) + HIERARCHY_SEPARATOR + adjust(name);
	}
	
	public String concat(String name){
		return concat(this.name, name);
	}
	
	private Named parent;
	
	/**
	 * <pre>
	 *  解析后的名字，已经把扩展内容去掉的名字，这个一般就是可用的名字 
	 *  </pre>
	 *  
	 *  注意：如果{@link #parent}不为null，则这个名字会把{@link #parent}的名字连接在一起计算
	 */
	private final String name;
	/** 如果名字使用的是"name.subname"等格式的，会被解析成一个数组 */
	private String[] names;
	
	private Named(){
		this.name = "";
	}
	
	public Named(String name){
		this.name  = name;
		this.names = name.split(HIERARCHY_SEPARATOR_REGEX);
	}

	public Named(Named parent, String name){
		this(concat(parent.name, name));
		this.parent = parent;
	}
	
	public Named getParent() {
		return parent;
	}
	
	public String getName() {
		return name;
	}
	
	public Named sub(String subname){
		return new Named(this, subname);
	}

	public boolean associated(){
		return names.length > 1;
	}

	public boolean associated(Named candidateParent){
		if(names.length > candidateParent.names.length){
			for(int i = 0; i < candidateParent.names.length; i++){
				if(!names[i].equals(candidateParent.names[i])){
					return false;
				}
			}
			return true;
		}
		return false;
	}
	
	public String getTargetName() {
		return name;
	}

	public String[] getNames() {
		return names;
	}

//	/** 表示给定的名字必须与定义的名字相同 */
//	public boolean is(String name){
//		return name.equals(this.name);
//	}
	
//	public boolean is(PropertiesName name){
//		return name.equals(this.name);
//	}

	/**
	 * <pre>
	 * 定义的名字如果是以给定的名字的前部分或全部相同的，则返回true
	 * 如：定义的是 nam， 给定的全名为 name或namefull，则返回true
	 * </pre>
	 */
	public boolean with(String fullName){
		String lowname = name.toLowerCase();
		String lowfull = fullName.toLowerCase();
		return lowfull.startsWith(lowname);
	}
	
	@Override
	public String toString() {
		return name;
	}
	
	@Override
	public int hashCode() {
		return name.hashCode();
	}
	
	@Override
	public boolean equals(Object obj) {
		if(null == obj) return false;
		if(this == obj) return true;
		
		/*
		 * 如果同是Named对象，则判断Named.name值是否相同
		 */
		if(obj instanceof Named){
			Named pn = (Named) obj;
			return name.equals(pn.name);
//			//是否两个的parent都为null
//			if(null == parent && null == pn.parent) return name.equals(pn.name);
//			
//			//两个parent都必须不能为空，并且相等的情况下，才能判断名字是否相等
//			if(null != parent && parent.equals(pn.parent)) return name.equals(pn.name);
//			return false;
		}
		
		/*
		 * 否则把obj当成是字符串进行处理
		 * 不能直接使用object对象进行判断，因为有可能这个值是计算出来的，如：PropertiesName
		 */
		return name.equals(obj.toString());
	}
}
